
#include <stdlib.h>
#include "SecurityTokenInteractive.h"

/** Constructor for the interactive-based security token.
 * 
 * @param ipassword The password to use. */
SecurityTokenInteractive::SecurityTokenInteractive(const char *ipassword)
{
   tried = 0;
   password = (ipassword) ? strdup(ipassword) : NULL;
}

/** Destructor for the interactive security token. */
SecurityTokenInteractive::~SecurityTokenInteractive()
{
   if (password) free(password);
   password = NULL;
}

/** Callback function for interactive authentication from libssh2. */
void *SecurityTokenInteractive::interactiveCallback(const char *name, int name_len,
   const char *instruction, int instruction_len, int num_prompts,
   const LIBSSH2_USERAUTH_KBDINT_PROMPT *prompts,
   LIBSSH2_USERAUTH_KBDINT_RESPONSE *responses, void **abstract)
{
   SecurityTokenInteractive *kthis = (SecurityTokenInteractive *)(*abstract);
   (void)name;
   (void)name_len;
   (void)instruction;
   (void)instruction_len;
   if (num_prompts == 1)
   {
      responses[0].text = strdup(kthis->password);
      responses[0].length = strlen(kthis->password);
   }
   for (int i = 0; i < instruction_len; i++)
      printf("%c\n", instruction[i]);
   (void)prompts;
   (void)abstract;
   return NULL;
}

/** SSH session authentication call.
 * 
 * @param tsession The SSH session to authenticate.
 * 
 * @param username The username to use with the interactive response
 * for SSH authentication.
 * 
 * @return Zero on success, negative on failure. */
int SecurityTokenInteractive::authenticateSSHSession(LIBSSH2_SESSION *tsession, const char *username)
{
   void **abstract_pointer = libssh2_session_abstract(tsession);
   *abstract_pointer = (void *)this;
   return libssh2_userauth_keyboard_interactive(tsession,
      (username) ? (username) : "",
      getInteractiveCallback());
}
